/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    can.c
  * @brief   This file provides code for the configuration
  *          of the CAN instances.
  ******************************************************************************
  * @attention
  *hn
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "can.h"

/* USER CODE BEGIN 0 */
#include "top_scheme.h"
/* USER CODE END 0 */

CAN_HandleTypeDef hcan2={0};

CAN_TxHeaderTypeDef CAN2_TxMessage = {0};//CAN2发送帧
uint8_t CAN2_TxData[10] = {0};//CAN2发送数据buf
CAN_RxHeaderTypeDef CAN2_RxMessage = {0};//CAN2接受帧
uint8_t CAN2_RxData[10] = {0};//CAN2接收数据buf
uint8_t mNodeId = 0x21;//从节点默认是 33站号开始

uint8_t sendData[10] = {0};//发送数据
//灯控-IO处理先关定义
uint8_t mIO_Order = 0;//命令数据 bit0-红，bit1-黄，bit2-绿
uint8_t mIO_Data = 0;//控制数据

/* CAN2 init function */
void MX_CAN2_Init(void)
{
	CAN_FilterTypeDef  sFilterConfig = {0};

  /* USER CODE BEGIN CAN2_Init 0 */

  /* USER CODE END CAN2_Init 0 */

  /* USER CODE BEGIN CAN2_Init 1 */
#if CAN
  /* USER CODE END CAN2_Init 1 */
  hcan2.Instance = CAN2;
  hcan2.Init.Prescaler = 6; //500k
  hcan2.Init.Mode = CAN_MODE_NORMAL;
  hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan2.Init.TimeSeg1 = CAN_BS1_7TQ;
  hcan2.Init.TimeSeg2 = CAN_BS2_6TQ;
  hcan2.Init.TimeTriggeredMode = DISABLE;
  hcan2.Init.AutoBusOff = DISABLE;
  hcan2.Init.AutoWakeUp = DISABLE;
  hcan2.Init.AutoRetransmission = DISABLE;
  hcan2.Init.ReceiveFifoLocked = DISABLE;
  hcan2.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan2) != HAL_OK)
  {
    Error_Handler();
  }

  sFilterConfig.FilterBank = 0;                       //???0
  sFilterConfig.FilterMode =  CAN_FILTERMODE_IDMASK;  //??????
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterIdHigh = 0X0000;   //??ID???STID?
  sFilterConfig.FilterIdLow  = 0X0000;
  sFilterConfig.FilterMaskIdHigh =0X0000;
  sFilterConfig.FilterMaskIdLow  =0X0000;
  sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;    //?????????FIFO0?
  sFilterConfig.FilterActivation = ENABLE;  	//?????
  sFilterConfig.SlaveStartFilterBank  = 0;
  HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig);

  HAL_CAN_Start(&hcan2);//使能CAN2
  /* USER CODE BEGIN CAN2_Init 2 */
#endif /*CAN*/
  /* USER CODE END CAN2_Init 2 */

}

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(canHandle->Instance==CAN2)
  {
  /* USER CODE BEGIN CAN2_MspInit 0 */
#if CAN
  /* USER CODE END CAN2_MspInit 0 */
    /* CAN2 clock enable */
    __HAL_RCC_CAN2_CLK_ENABLE();
    __HAL_RCC_CAN1_CLK_ENABLE();

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**CAN2 GPIO Configuration
    PB5     ------> CAN2_RX
    PB6     ------> CAN2_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    //CAN2 中断配置
    HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);

    HAL_NVIC_SetPriority(CAN2_TX_IRQn, 2, 1);
    HAL_NVIC_DisableIRQ(CAN2_TX_IRQn);
  /* USER CODE BEGIN CAN2_MspInit 1 */
#endif /*CAN*/
  /* USER CODE END CAN2_MspInit 1 */
  }
}

void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{

  if(canHandle->Instance==CAN2)
  {
  /* USER CODE BEGIN CAN2_MspDeInit 0 */
#if CAN
  /* USER CODE END CAN2_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_CAN2_CLK_DISABLE();
    __HAL_RCC_CAN1_CLK_DISABLE();

    /**CAN2 GPIO Configuration
    PB5     ------> CAN2_RX
    PB6     ------> CAN2_TX
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_5|GPIO_PIN_6);

    HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn);
    HAL_NVIC_DisableIRQ(CAN2_TX_IRQn);
  /* USER CODE BEGIN CAN2_MspDeInit 1 */
#endif /*CAN*/
  /* USER CODE END CAN2_MspDeInit 1 */
  }
}

void CAN2_RX0_IRQHandler(void)
{
  HAL_CAN_IRQHandler(&hcan2);
}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* hcan)
{
	HAL_StatusTypeDef ret = 0;
	// 收到消息时的回调函数
	if(hcan->Instance==CAN2)
	{
		ret = HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &CAN2_RxMessage, CAN2_RxData);
		if(ret==HAL_OK)
		{

		}
	}
  // ... 处理接收到的数据 ...
}

//CAN2数据发送函数
void CAN2_Send_Msg(uint8_t nodeId, uint8_t* msg, uint8_t len)
{
	uint8_t i =0;
	uint32_t TxMailbox = 1;
	HAL_StatusTypeDef ret = 0;

	CAN2_TxMessage.DLC = len;
	CAN2_TxMessage.StdId = nodeId;
	CAN2_TxMessage.IDE = CAN_ID_STD;
	CAN2_TxMessage.RTR = CAN_RTR_DATA;
    if (NULL != msg)
	{
		for(i=0; i< len; i++)
		{
			CAN2_TxData[i] = msg[i];
		}
		ret = HAL_CAN_AddTxMessage(&hcan2, &CAN2_TxMessage, CAN2_TxData, &TxMailbox);
		if(ret != HAL_OK)
		{
			i =0;
		}
		else
		{
			i =0;
		}
	}
}

uint8_t light_step = 3;
void RED_control(void)//红灯亮 其他灭
{
	if(light_step)
	{
		switch (light_step)
		{
			case 0x03:
			{
				sendData[0] = EXTEND_FUN_WRITE;
				sendData[1] = (uint8_t)(EXT_ADDR_OUT_PORT >> 8);
				sendData[2] = (uint8_t)(EXT_ADDR_OUT_PORT);
				sendData[3] = 0;
				sendData[4] = 0;
				sendData[5] = 0;
				sendData[6] = 0;
				if (mIO_Data == IO_CONTROL_SET)
				{
					sendData[7] = 1;
				}
				else
				{
					sendData[7] = 0;
				}
				CAN2_Send_Msg(mNodeId, sendData, 8);
				break;
			}
			case 0x02:
			{
				//绿灯
				sendData[1] = (uint8_t)((EXT_ADDR_OUT_PORT+1) >> 8);
				sendData[2] = (uint8_t)(EXT_ADDR_OUT_PORT+1);
				sendData[7] = 0;
				CAN2_Send_Msg(mNodeId, sendData, 8);
				break;
			}
			case 0x01:
			{
				//黄灯
				sendData[1] = (uint8_t)((EXT_ADDR_OUT_PORT+2) >> 8);
				sendData[2] = (uint8_t)(EXT_ADDR_OUT_PORT+2);
				sendData[7] = 0;
				CAN2_Send_Msg(mNodeId, sendData, 8);
				mIO_Order &= 0xFE;//bit0清零，表示处理完
				break;
			}
		}
		light_step--;
	}
}


void GREEN_control(void)//绿灯亮 其他灭
{
	if(light_step)
	{
		switch (light_step)
		{
			case 0x03:
			{
				sendData[0] = EXTEND_FUN_WRITE;
				sendData[1] = (uint8_t)((EXT_ADDR_OUT_PORT+2) >> 8);
				sendData[2] = (uint8_t)(EXT_ADDR_OUT_PORT+2);
				sendData[3] = 0;
				sendData[4] = 0;
				sendData[5] = 0;
				sendData[6] = 0;
				if (mIO_Data == IO_CONTROL_SET)
				{
					sendData[7] = 1;
				}
				else
				{
					sendData[7] = 0;
				}
				CAN2_Send_Msg(mNodeId, sendData, 8);
				break;
			}
			case 0x02:
			{
				//红灯
				sendData[1] = (uint8_t)(EXT_ADDR_OUT_PORT >> 8);
				sendData[2] = (uint8_t)(EXT_ADDR_OUT_PORT);
				sendData[7] = 0;
				CAN2_Send_Msg(mNodeId, sendData, 8);
				break;
			}
			case 0x01:
			{
				//黄灯
				sendData[1] = (uint8_t)((EXT_ADDR_OUT_PORT+1) >> 8);
				sendData[2] = (uint8_t)(EXT_ADDR_OUT_PORT+1);
				sendData[7] = 0;
				CAN2_Send_Msg(mNodeId, sendData, 8);
				mIO_Order &= 0xFB;//bit2清零，表示处理完
				break;
			}
		}
		light_step--;
	}
}

void YELLOW_control(void)//黄灯亮 其他灭
{
	if(light_step)
	{
		switch (light_step)
		{
			case 0x03:
			{
				sendData[0] = EXTEND_FUN_WRITE;
				sendData[1] = (uint8_t)((EXT_ADDR_OUT_PORT+1) >> 8);
				sendData[2] = (uint8_t)(EXT_ADDR_OUT_PORT+1);
				sendData[3] = 0;
				sendData[4] = 0;
				sendData[5] = 0;
				sendData[6] = 0;
				if (mIO_Data == IO_CONTROL_SET)
				{
					sendData[7] = 1;
				}
				else
				{
					sendData[7] = 0;
				}
				CAN2_Send_Msg(mNodeId, sendData, 8);
				break;
			}
			case 0x02:
			{
				//红灯
				sendData[1] = (uint8_t)(EXT_ADDR_OUT_PORT >> 8);
				sendData[2] = (uint8_t)(EXT_ADDR_OUT_PORT);
				sendData[7] = 0;
				CAN2_Send_Msg(mNodeId, sendData, 8);
				break;
			}
			case 0x01:
			{
				//绿灯
				sendData[1] = (uint8_t)((EXT_ADDR_OUT_PORT+2) >> 8);
				sendData[2] = (uint8_t)(EXT_ADDR_OUT_PORT+2);
				sendData[7] = 0;
				CAN2_Send_Msg(mNodeId, sendData, 8);
				mIO_Order &= 0xFD;//bit1清零，表示处理完
				break;
			}
		}
		light_step--;
	}
}

//灯处理函数
void EXT_IO_Process(void)
{
	if (mIO_Order & IO_ORDER_RED)
	{
		RED_control();
	}
	if (mIO_Order & IO_ORDER_YELLOW)
	{
		YELLOW_control();
	}
	if (mIO_Order & IO_ORDER_GREEN)
	{
		GREEN_control();
	}

//	if (mIO_Order & IO_ORDER_RED)
//	{//红
//		sendData[0] = EXTEND_FUN_WRITE;
//		sendData[1] = (uint8_t)(EXT_ADDR_OUT_PORT >> 8);
//		sendData[2] = (uint8_t)(EXT_ADDR_OUT_PORT);
//		sendData[3] = 0;
//		sendData[4] = 0;
//		sendData[5] = 0;
//		sendData[6] = 0;
//		if (mIO_Data == IO_CONTROL_SET)
//		{
//			sendData[7] = 1;
//		}
//		else
//		{
//			sendData[7] = 0;
//		}
//		CAN2_Send_Msg(mNodeId, sendData, 8);
//		mIO_Order &= 0xFE;//bit0清零，表示处理完
//	}
//
//	if (mIO_Order & IO_ORDER_YELLOW)
//	{//黄
//		sendData[0] = EXTEND_FUN_WRITE;
//		sendData[1] = (uint8_t)((EXT_ADDR_OUT_PORT+1) >> 8);
//		sendData[2] = (uint8_t)(EXT_ADDR_OUT_PORT+1);
//		sendData[3] = 0;
//		sendData[4] = 0;
//		sendData[5] = 0;
//		sendData[6] = 0;
//		if (mIO_Data == IO_CONTROL_SET)
//		{
//			sendData[7] = 1;
//		}
//		else
//		{
//			sendData[7] = 0;
//		}
//		CAN2_Send_Msg(mNodeId, sendData, 8);
//		mIO_Order &= 0xFD;//bit1清零，表示处理完
//	}
//
//	if (mIO_Order & IO_ORDER_GREEN)
//	{//绿
//		sendData[0] = EXTEND_FUN_WRITE;
//		sendData[1] = (uint8_t)((EXT_ADDR_OUT_PORT+2) >> 8);
//		sendData[2] = (uint8_t)(EXT_ADDR_OUT_PORT+2);
//		sendData[3] = 0;
//		sendData[4] = 0;
//		sendData[5] = 0;
//		sendData[6] = 0;
//		if (mIO_Data == IO_CONTROL_SET)
//		{
//			sendData[7] = 1;
//		}
//		else
//		{
//			sendData[7] = 0;
//		}
//		CAN2_Send_Msg(mNodeId, sendData, 8);
//		mIO_Order &= 0xFB;//bit2清零，表示处理完
//	}
}



/* USER CODE BEGIN 1 */

/* USER CODE END 1 */
